$nolist
$include(Include\reg832.PDF)
$list

; declaratie interrupt adressen code

codestart   equ   0000h
ext0_int    equ   0003h
timer0_int  equ   000bh
ext1_int    equ   0013h
timer1_int  equ   001bh
serial_int  equ   0023h
timer2_int  equ   002bh
adc_int     equ   0033h
spii2c_int  equ   003bh
psm_int     equ   0043h
timer3_int  equ   0053h
wds_int     equ   005bh


; declaratie constanten programma algemeen

;cr			equ     00dh	;ascii code voor wagenterugloop
;lf			equ     00ah	;ascii code voor line feed (cursor tweede lijn)
cursoff     equ     003h	;ascii code uitschakelen van de cursor

; adres waar stack zal starten (groeit naar hogere adressen)
stack       equ     07fh	; vanaf hiet zit de stack in het geheugen


; declare variabelen met bits
serialf		equ		02fh.0
serialv	 	equ		02fh.1				
serialh		equ		02fh.2
seriald		equ		02fh.3
error		equ		02fh.4
; declaratie adc read buffer
adcbuffl	equ		030h
adcbuffh	equ		038h
; program variabelen declaratie locatie
adcbufptr	equ		040h
adcgemh		equ		041h
adcgeml		equ		042h	
avgsuml		equ		043h
avgsumh		equ		044h
writedsp	equ		045h
writedspc	equ		046h
volthexl	equ		047h
volthexh	equ		048h
voltbcdl	equ		049h
voltbcdh	equ		04ah
freqhexl	equ		04bh
freqhexh	equ		04ch
freqbcdl	equ		04dh
freqbcdh	equ		04eh
serialpos	equ		04fh
;declaratie variabelen DDS
Fadderl     equ   	050h
Fadderm     equ   	051h
Fadderh     equ   	052h
Fincl       equ   	053h
Finch       equ   	054h
; error vars
errorcount	equ		055h
						

; interupt vectors
			org   	codestart         ;reset vector
            ljmp  	start
            org   	ext0_int          ;ext int0
           	reti
            org   	timer0_int        ;timer0 int
            ljmp  	timer_143us       ;timeroverflow om de 143us
            org   	ext1_int          ;ext int1
            reti
            org   	timer1_int        ;timer1 int
            reti
            org   	serial_int        ;serial interrupts
            ljmp	serial_intr
            org   	timer2_int        ;timer2 overflow interrupt om de 500us
            reti
            org   	adc_int           ;adc int
            ljmp	adc_1ms_intr
            org   	spii2c_int        ;spi en iic interrupts
            reti
            org   	psm_int           ;psm int
            reti
            org   	timer3_int        ;timer3 int
            reti
            org   	wds_int           ;watchdog int
            reti

; start program
start:      clr		p2.0   		; set lampke rechts onder
            mov     sp,#stack   ; stakske laden

			mov		pllcon,#01001000b 	; set to fastest speed!

			lcall	initlcd		; init display
			lcall	initsio		; init serial input output
			lcall	initadc		; init adc for battery
			lcall	initt2 		; init t2
			
			
			setb	ea			; enable interupts
			setb	es			; set serial interrupt
			setb	eadc		; enable adc interrupts

			setb	tr2			; enable timer 2

			mov		adcgemh,#0
			mov 	adcgeml,#0
			mov		writedsp,#0
			mov		writedspc,#20
			mov		serialpos,#0
			mov   	Fincl,#98h        ;50hz=1d4ch=7500d
            mov   	Finch,#3ah        ;100Hz=3a98h=15000d
;start dds init
;timer0 init
            mov   th0,#038h         ;65536-200= reload waarde
            mov   tl0,#038h         ;143us overflowtime!
       	    mov	  TMOD,#00000010b
;DAC init
            mov   daccon,#11101101b
;interrupt init
            setb  tr0               ;Timer1 runmode
			setb  et0               ;Timer0 interrupts on

            
; -------------------------------------------
; ------------ Main program loop ------------
; -------------------------------------------        							
main:		mov		a,writedsp
			jz		main
			mov		writedsp,#1
			
			; set cursor 0
			mov		a,#cr                   ; carrege return
			lcall   outcharlcd      
			mov		a,#cursoff              ; cursor off
			lcall   outcharlcd

			; show voltage
			lcall 	calc_volt
			mov		a,#10001010b	 	; go to 10 place on first line 
			lcall	outcharlcd
			mov		a,voltbcdh
			lcall 	outniblcd
			mov		a,#'.'
			lcall	outcharlcd
			mov		a,voltbcdl
			lcall	outbytelcd
			mov		a,#'V'
			lcall	outcharlcd

			; show frequentie
			lcall 	calc_freq 
			mov		a,#10000000b	 	; go to 0 place on first line 
			lcall	outcharlcd
			mov		a,freqbcdh
			lcall 	outniblcd
			mov		a,freqbcdl
			swap	a
			lcall	outniblcd
			mov		a,#10000010b	 	; go to 2 place on first line
			lcall	outcharlcd 
			mov		a,#'.'
			lcall	outcharlcd
			mov		a,freqbcdl
			lcall	outniblcd
			mov		a,#'H'
			lcall	outcharlcd
			mov		a,#'z'
			lcall	outcharlcd

			; error
			jnb		error,main_end
			mov		a,errorcount
			cjne	a,#0,main_err1

			clr		p2.7
			clr		p2.6
			clr		p2.5
			sjmp	main_err_c

main_err1:	cjne	a,#25,main_err_c

			setb	p2.7
			setb	p2.6
			setb	p2.5	

main_err_c:	inc		errorcount
			mov		a,errorcount
			cjne	a,#50,main_end

			mov		errorcount,#0
			

main_end:  	ljmp	main			

; ---------------------------------------------------------
; -- routine to calculate voltage from avarege adc value --
; -- input: adcgemh,adcgeml
; -- output: volthhex,voltlhex in 0,01V	 (0 - 500)
; -- output: volthbcd,voltlbcd
; ---------------------------------------------------------

calc_volt:
			mov		r1,adcgemh
			mov		r0,adcgeml
			mov		r3,#0
			mov		r2,#8
			lcall	div16
			mov		volthexh,r3
			mov		volthexl,r2
			mov		r1,volthexh
			mov		r0,volthexl
			lcall	hexbcd16
			mov		voltbcdh,r1
			mov		voltbcdl,r0
			ret

; -----------------------------------------------------------
; -- routine to calculate frequence from avarege adc value --
; -- input: adcgemh,adcgeml
; -- output: freqhexh,freqhexl in 0,1Hz	 (0 - 1000)
; -- output: freqbcdh,freqbcdl
; -----------------------------------------------------------

calc_freq:
			mov		r1,adcgemh
			mov		r0,adcgeml
			; calculate hex value in 0.1Hz
			mov		r3,#0
			mov		r2,#4
			lcall	div16
			mov		freqhexh,r3
			mov		freqhexl,r2
			; calculate bcd value in 0.1Hz
			mov		r1,freqhexh
			mov		r0,freqhexl
			lcall	hexbcd16
			mov		freqbcdh,r1
			mov		freqbcdl,r0
			; calculate DDS finch,fincl
			mov		r1,freqhexh
			mov		r0,freqhexl
			mov		r3,#0
			mov		r2,#15	
			lcall	mul16
			mov		Fincl,r0
			mov		Finch,r1
			ret

; ------------------------------------------------------
; -- routine to calculate average of 8, 12 bit values --
; ------------------------------------------------------
calc_avg:	push	0
			push	1
			push	2

			mov		r0,#adcbuffl
			mov		r1,#adcbuffh

			mov		avgsuml,#0	
			mov		avgsumh,#0		
			mov		r2,#8

calc_avg1:	mov		a,avgsuml		; load total low byte	
			add		a,@r0			; add next byte
			mov		avgsuml,a
			
			mov		a,avgsumh
			addc	a,#000h	
			mov		avgsumh,a	

			mov		a,avgsumh
			add		a,@r1
			mov		avgsumh,a
			
			inc		r0				; increase pointer
			inc 	r1				; increase pointer

 			djnz	r2,calc_avg1   	; jump until 8 add's are done

			; divide
			mov		a,avgsuml		;divide low bits
			mov		b,#008h
			div		ab
			mov		r2,a
			
			mov		a,avgsumh		; take 3 low bits of high byte, and but them before 5 low bits
			anl		a,#007h			; to make total 8 bit low byte
			mov		b,#020h
			mul		ab
			orl		a,r2
			mov		adcgeml,a

			mov		a,avgsumh		; take 5 high bits of high byte, and make then 5 low bits.
			mov		b,#008h
			div		ab
			mov		adcgemh,a

			pop		2
			pop		1
			pop		0

			ret

; ----------------------------------------------------
; -- interrupt routine voor adc
; ----------------------------------------------------
adc_1ms_intr:	push    acc
				push    dpl
				push    dph
				push	psw
				push	0
				push	1

				; every 20 ms
				djnz	writedspc,adc_1ms_intr1
				mov		writedsp,#1
				mov		writedspc,#20
adc_1ms_intr1:
				;increase pointers
				mov		a,adcbufptr
				add		a,#1
				anl		a,#007h
				add		a,#adcbuffl
				mov		r0,a
				mov		adcbufptr,a

				add		a,#8
				mov		r1,a

				; lsb
				mov		a,adcdatal
				mov		@r0,a

				; msb
				mov		a,adcdatah
				anl		a,#00Fh	   	; remove channel number
				mov		@r1,a

				lcall	calc_avg	; calculate avarage
				
				; finish routine
				pop		1
				pop		0
				pop		psw
			   	pop		dph
				pop		dpl
				pop		acc
				reti

; ----------------------------------------------------
; interrupt routine serial uart
; ----------------------------------------------------
serial_intr:	push 	acc
				push	psw
				push  	dpl
				push  	dph
				push	0
				push	1
				push	2

				jb		ri,serial_start		; jump to end if bit is no recieve interrupt
				ljmp	serial_end
serial_start:	

				lcall	inchar
				mov		r2,a
				lcall 	outchar
				
				mov		r0,serialpos	 	; put serial position in r0
				cjne	r2,#':',serial_nonew
				; clear all
				mov		r0,#0
				clr		serialf
				clr		serialv
				clr		serialh
				clr		seriald
				clr		error
				setb	p2.7
				setb	p2.6
				setb	p2.5
				ljmp	serial_end

serial_nonew:	cjne	r2,#'F',serial_nofreq
				cjne	r0,#0,serial_error
				mov		r0,#1
				setb	serialf
				ljmp	serial_end

serial_nofreq:	cjne	r2,#'V',serial_novolt
				cjne	r0,#0,serial_error
				mov		r0,#1
				setb	serialv
				ljmp	serial_end

serial_novolt:	cjne	r2,#'H',serial_nohex
				cjne	r0,#1,serial_error
				jnb		serialf,serial_error
				setb	serialh
				mov		r0,#2
				ljmp	serial_end

serial_nohex:	cjne	r2,#'D',serial_nodec
				cjne	r0,#1,serial_error
				setb	seriald
				mov		r0,#2
				ljmp	serial_end

serial_nodec:	cjne	r2,#cr,serial_error
				cjne	r0,#2,serial_error
				jnb		serialf,serial_nodec_v
				jnb		serialh,serial_nodec_d
				; send serial f h
				lcall	serial_send_fh
				ljmp	serial_end
serial_nodec_d:	jnb		seriald,serial_error
				; send serial f d
				lcall	serial_send_fd
				ljmp	serial_end
serial_nodec_v:	jnb		serialv,serial_error
				jnb		seriald,serial_error
				; send serial v d
				lcall	serial_send_vd
				ljmp	serial_end

serial_error:	
				setb	error
				mov		errorcount,#0	
				ljmp	serial_end


serial_end:		; einde jump
				mov		serialpos,r0			; put r0 back in serial position

				pop		2
				pop		1
				pop		0
				pop		dph
				pop		dpl
				pop 	psw
				pop		acc
				reti

; --------------------------------------------------------------------
; -- Functie die de frequentie hexadecimaal doorstuurt serieel -------
; --------------------------------------------------------------------
serial_send_fh:	mov 	a,freqhexh
				lcall	outbyte
				mov		a,freqhexl
				lcall	outbyte
				mov		a,#cr
				lcall	outchar
				mov		a,#lf
				lcall	outchar

				ret
; --------------------------------------------------------------------
; -- Functie die de frequentie decimaal doorstuurt serieel -----------
; --------------------------------------------------------------------
serial_send_fd:	mov		a,freqbcdh
				lcall	outnib
				mov		a,freqbcdl
				swap	a
				lcall	outnib
				mov		a,#'.'
				lcall	outchar
				mov		a,freqbcdl
				lcall	outnib
				mov		a,#'H'
				lcall	outchar
				mov		a,#'z'
				lcall	outchar
				mov		a,#cr
				lcall	outchar
				mov		a,#lf
				lcall	outchar

				ret
; --------------------------------------------------------------------
; -- Functie die de spanning deicmaal doorstuurt serieel -------------
; --------------------------------------------------------------------
serial_send_vd:	mov		a,voltbcdh
				lcall	outnib
				mov		a,#'.'
				lcall	outchar
				mov		a,voltbcdl
				lcall	outbyte
				mov		a,#'V'
				lcall	outchar
				mov		a,#cr
				lcall	outchar
				mov		a,#lf
				lcall	outchar
				
				ret

;---------------------------------------------------------------------------------------------
;interruptroutine wordt uitgevoerd met een frequentie van:
;16,777216MHz/(12*(65536-reload))=6.99050666kHz--> 143.051147us (bij 65536-200d reload)
;de interruptroutine duurt 28.61 us @16.777216MHz.
;Dit is de DDS routine, met een 20 bit accumulator waarvan de 8 hoogste bits worden gebruikt
;om de sinustabel aan te spreken.Het fase-increment is een 16 bit register.
;---------------------------------------------------------------------------------------------
timer_143us:push  acc
            push  psw
            push  b

            mov   a,Fadderl
            add   a,Fincl
            mov   Fadderl,a
            mov   a,Fadderm
            addc  a,Finch
            mov   Fadderm,a
            mov   b,a
            mov   a,Fadderh
            addc  a,#0
            mov   Fadderh,a
            mov   a,b
            anl   a,#0f0h
            swap  a
            mov   b,a
            mov   a,Fadderh
            anl   a,#0fh
            swap  a
            add   a,b
            mov   dpl,a
            mov   dph,#08h
            mov   a,#0
            movc  a,@a+dptr
            mov   dac0l,a

            pop   b
            pop   psw
            pop   acc
            reti
            

; --------------------------------------------------------------------
; -- Functie die het Timer 2 initialiseert ---------------------------
; --------------------------------------------------------------------

initt2:		mov		t2con,#00000000b 
			mov		th2,#0FAh
			mov		tl2,#08Ah
			mov		rcap2h,#0FAh
			mov		rcap2l,#08Ah
            ret


; --------------------------------------------------------------------
; -- Functie die het ADC initialiseert -------------------------------
; --------------------------------------------------------------------

initadc:	mov		adccon1,#10011110b 
			mov		adccon2,#00000111b
			mov		adccon3,#01000111b
            ret


; --------------------------------------------------------------------
; -- 256 stappen sinusgolf tabel -------------------------------------
; --------------------------------------------------------------------

; 
          org   00800h

sine:	  db	080h,083h,086h,089h,08ch,08fh,092h,095h,098h,09ch,09fh,0a2h,0a5h,0a8h,0abh,0aeh
	      db	0b0h,0b3h,0b6h,0b9h,0bch,0bfh,0c1h,0c4h,0c7h,0c9h,0cch,0ceh,0d1h,0d3h,0d5h,0d8h
	      db	0dah,0dch,0deh,0e0h,0e2h,0e4h,0e6h,0e8h,0eah,0ech,0edh,0efh,0f0h,0f2h,0f3h,0f5h
	      db	0f6h,0f7h,0f8h,0f9h,0fah,0fbh,0fch,0fch,0fdh,0feh,0feh,0ffh,0ffh,0ffh,0ffh,0ffh
	      db	0ffh,0ffh,0ffh,0ffh,0ffh,0ffh,0feh,0feh,0fdh,0fch,0fch,0fbh,0fah,0f9h,0f8h,0f7h
	      db	0f6h,0f5h,0f3h,0f2h,0f0h,0efh,0edh,0ech,0eah,0e8h,0e6h,0e4h,0e2h,0e0h,0deh,0dch
	      db	0dah,0d8h,0d5h,0d3h,0d1h,0ceh,0cch,0c9h,0c7h,0c4h,0c1h,0bfh,0bch,0b9h,0b6h,0b3h
	      db	0b0h,0aeh,0abh,0a8h,0a5h,0a2h,09fh,09ch,098h,095h,092h,08fh,08ch,089h,086h,083h
	      db	080h,07ch,079h,076h,073h,070h,06dh,06ah,067h,063h,060h,05dh,05ah,057h,054h,051h
	      db	04fh,04ch,049h,046h,043h,040h,03eh,03bh,038h,036h,033h,031h,02eh,02ch,02ah,027h
	      db	025h,023h,021h,01fh,01dh,01bh,019h,017h,015h,013h,012h,010h,00fh,00dh,00ch,00ah
	      db	009h,008h,007h,006h,005h,004h,003h,003h,002h,001h,001h,000h,000h,000h,000h,000h
	      db	000h,000h,000h,000h,000h,000h,001h,001h,002h,003h,003h,004h,005h,006h,007h,008h
	      db	009h,00ah,00ch,00dh,00fh,010h,012h,013h,015h,017h,019h,01bh,01dh,01fh,021h,023h
	      db	025h,027h,02ah,02ch,02eh,031h,033h,036h,038h,03bh,03eh,040h,043h,046h,049h,04ch
	      db	04fh,051h,054h,057h,05ah,05dh,060h,063h,067h,06ah,06dh,070h,073h,076h,079h,07ch
;sine:	  	db	000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
;	     	db	000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
;	      	db	000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
;	      	db	000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
;	      	db	000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
;	      	db	000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
;	      	db	000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
;	      	db	000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h,000h
;	      	db	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
;	      	db	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
;	      	db	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
;	      	db	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
;	      	db	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
;	      	db	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
;	      	db	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh
;	      	db	0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh,0FFh

; required includes
$include(Include\51math2.inc)
$include(Include\aduclcd1.inc)       ;includen van de LCD driver   
$include(Include\ADuCsio0.inc)
			
			end